﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using BEPUphysics.Entities;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics;

namespace Brain.Bepu
{
    public class PhysicObject_Sphere : IPhysicsObject3D
    {
        public Vector3 RotationRadians
        {
            get { return Vector3.Zero; }
            set { Orientation = QuaternionUtil.CreateQuaternion(value); }
        }
        public void Dispose()
        {
            this.Space.Remove(this.Sphere);
        }
        public event SetVoid OnUpdate;
        public Quaternion Orientation
        {
            get { return Sphere.Orientation; }
            set { Sphere.Orientation = value; }
        }
        public float Radius
        {
            get { return Sphere.Radius; }
            set { Sphere.Radius = value; }
        }
        public Vector3 AngularVelocity
        {
            get
            {
                return Sphere.AngularVelocity;
            }
            set
            {
                Sphere.AngularVelocity = value;
            }
        }

        public Sphere Sphere;

        public Vector3 Scale
        {
            get
            {
                return new Vector3(Sphere.Radius);
            }
            set
            {
                // Yes, I know there are equations for doing stuff like this,
                // but I think this will be more useful
                Sphere.Radius = Vector3Util.Average(value);
            }
        }

        public object Tag { get; set; }

        public Vector3 Position
        {
            get { return Sphere.Position; }
            set { Sphere.Position = value; }
        }

        public bool Immovable
        {
            get { return !Sphere.IsDynamic; }
            set
            {
                Sphere.BecomeKinematic();
            }
        }

        public float Mass
        {
            get { return Sphere.Mass; }
            set { Sphere.Mass = value; }
        }

        public Vector3 LinearVelocity
        {
            get
            {
                return Sphere.LinearVelocity;
            }
            set
            {
                Sphere.LinearVelocity = value;
            }
        }

        public Space Space { get; protected set; }

        public PhysicObject_Sphere(Space space)
            : base()
        {
            ShouldSerialize = true;
            this.Sphere = new Sphere(Vector3.Zero, 1);
            this.Space = space;
            Space.Add(Sphere);
            Sphere.PositionUpdated += new Action<Entity>(Sphere_PositionUpdated);

            this.Immovable = false;
            this.Mass = 1;
            this.Tag = this.Sphere;
            this.Sphere.Tag = this;
        }

        void Sphere_PositionUpdated(Entity obj)
        {
            if (OnUpdate != null)
            {
                OnUpdate();
            }
        }

        public bool ShouldSerialize { get; set; }

        public void SerializeData(SerializationData parentData, string index)
        {
            // We do NOT need to serialize Position/Scale:
            // Position : The WorldObject parent of this PhysicsObject will save the Position
            // Scale    : The WorldObject has an Offset for setting this Scale

            parentData.AddData("PO.Rotation", this.Orientation, index);
            parentData.AddData("PO.Immovable", this.Immovable, index);
            parentData.AddData("PO.Name", this.Sphere.BrainIdentifier, index);
        }

        public void DeserializeData(SerializationData parentData, string index)
        {
            this.Orientation = parentData.GetData<Quaternion>("PO.Rotation", index);
            this.Immovable = parentData.GetData<bool>("PO.Immovable", index);
            this.Sphere.BrainIdentifier = parentData.GetData<string>("PO.Name", index);
        }

        public void DeserializedAll()
        {
        }
    }
}
